''' Core bootstrapping module

Module is responsible for bootstrapping application core.
Module is called with config file name as argument.
'''
import path
path.update_sys_path(path.APP_ROOT, path.SYS_PATH)

import os
import sys
import ConfigParser
import logging
from multiprocessing import Queue
import tinyesb.process.bus as bus
import scopt.mpu as mpu
import scopt.watchdog as watchdog
import scopt.util.i18n as i18n
import scopt.process.http_in_gui_port as http_in_gui_port

logging.disable("WARNING")

# Request i18n configuration from underlying modules and install language
# handler.
_DEFAULT_LANGUAGE = 'en_EN'
_I18N_PATHS = {}
_I18N_PATHS.update(mpu.I18N)
_I18N_PATHS.update({'scopt': os.path.join(path.APP_ROOT, 'i18n')})
i18n.install(_I18N_PATHS, _DEFAULT_LANGUAGE)

if __name__ == '__main__':
    # Load config file from bootstrap argument and update APP section with
    # data directory. Data directory value is replacement parameter for
    # {DATA_DIR} anywhere in config file.
    config_file = sys.argv[1]
    config = ConfigParser.RawConfigParser()
    config.read(config_file)
    config.set('APP', 'DATA_DIR', os.path.join(path.APP_ROOT, "data"))

    # Processes definition section
    # Define processes and queues
    #
    # TODO: Pack firmware and related handlers into deployable package
    bus_queue = Queue()
    http_in_port_queue = Queue()

    http_in_process_def = {'target': http_in_gui_port.start,
                           'args': [config.getint('HTTP_I2_PORT', 'PORT_port'),
                                    config.get('HTTP_I2_PORT', 'PORT_url'),
                                    path.APP_ROOT,
                                    config.get('GUI', 'guiname'),
                                    bus.Channel('HTTP_IN',
                                               bus_queue,
                                               http_in_port_queue)]}

    ports = {'HTTP_IN': http_in_port_queue}

    bus_process_def = {'target': bus.start,
                       'args': [ports,
                                mpu.firmware(config),
                                mpu.exception_handler,
                                bus_queue]}

    watchdog_processes = {'BUS_PROC': {'process_def': bus_process_def,
                                       'control_queue': bus_queue},
                          'HTTP_IN_PROC': {'process_def': http_in_process_def,
                                           'control_queue': http_in_port_queue}}

    watchdog_port = config.getint('WATCHDOG', 'port')

    # Request watchdog process manager to bootstrap processes
    watchdog_thread = watchdog.start(watchdog_port, watchdog_processes)
    print('SCOPT: Started.')

    # Based on config parameter, if application is run in workstation mode,
    # eventually provide user with comfortable way of starting GUI.
    gui_port = config.getint('HTTP_I2_PORT', 'PORT_port')
    app_mode = (config.get('APP', 'mode'))
    if app_mode == 'workstation':
        try:
            from scopt import appdialog
            appdialog.show(gui_port, watchdog_port)
        except ImportError:
            from scopt.util.misc import ascii_info
            ascii_info([_('scopt.ttk.importerror.ln1'),
                        _('scopt.ttk.importerror.ln2'),
                        _('scopt.ttk.importerror.ln3')])
    elif app_mode == 'server':
        pass
    elif app_mode == 'development':
        import webbrowser
        webbrowser.open('http://localhost:{0}'.format(gui_port))

    # Wait for watchdog thread termination. No watchdog, no processes.
    # Application is terminated.
    watchdog_thread.join()
    print('SCOPT: Stopped.')
